package com.adwyxx.reflection;

import java.lang.annotation.*;

/**
 * 自定义注解 MyAnnotation
 * 可以通过四个元注解：
 * <pre>
 * {@code @Retention}: 声明周期
 * {@code @Target}: 使用位置
 * {@code @Inherited}: 是否被继承
 * {@code @Documented}: 是否被生成到API文档中，非必要
 * </pre>
 * ElementType 枚举类，用于指定注解可以使用的位置，枚举值的含义：
 * <pre>
 * - ElementType.TYPE：能修饰类、接口或枚举类型
 * - ElementType.FIELD：能修饰成员变量
 * - ElementType.METHOD：能修饰方法
 * - ElementType.PARAMETER：能修饰参数
 * - ElementType.CONSTRUCTOR：能修饰构造器
 * - ElementType.LOCAL_VARIABLE：能修饰局部变量
 * - ElementType.ANNOTATION_TYPE：能修饰注解
 * - ElementType.PACKAGE：能修饰包
 * </pre>
 * RetentionPolicy 表示注解存在的生命周期，枚举值的含义：
 * <pre>
 * - RetentionPolicy.SOURCE： 注解只在源代码中存在，编译成class之后，就没了。@Override 就是这种注解。
 * - RetentionPolicy.CLASS： 注解在java文件编程成.class文件后，依然存在，但是运行起来后就没了。@Retention的默认值，即当没有显式指定@Retention的时候，就会是这种类型。
 * - RetentionPolicy.RUNTIME： 注解在运行起来之后依然存在，程序可以通过反射获取这些信息
 * </pre>
 * @author Leo.W
 * @date 2024-09-11 15:23
 */
@Inherited // 注解是否可以被继承
// 注解使用位置，可以是多个，本例中依次为：类/接口、构造器、方法、成员变量（字段）、参数
@Target({ElementType.TYPE,ElementType.CONSTRUCTOR,ElementType.METHOD,ElementType.FIELD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME) // 注解声明周期，只有 RUNTIME 生命周期才能在运行时通过反射获取注解
public @interface MyAnnotation {
    /**
     * 配置参数：Annotation 的成员在 Annotation 定义中以无参数有返回值的抽象方法的形式来声明
     * - 可以使用 default 关键字为抽象方法指定默认返回值
     * - 如果只有一个抽象方法需要赋值，且方法名为value，可以省略“value=”，所以如果注解只有一个抽象方法成员，建议使用方法名value
     * @return 返回值类型只能是八种基本数据类型、String类型、Class类型、enum类型、Annotation类型、以上所有类型的数组
     */
    String value() default "";
}
